/*
 * L9Sound.cpp
 *
 *  Created on: 2011-10-18
 *      Author: baixp
 */

#include "../inc/L9Sound.h"
#include "L9Log.h"
namespace lib9bada {
/**
 * L9Sound使用L9Sprite提供的声音数据资源来创建，参数nChannel为播放频道,常常设置为2，一个代表背景音乐，一个代表播放的声音
 *
 * @param sprite
 *            L9Sprite
 * @param nChannel
 *            int
 */
L9Sound::L9Sound(L9Sprite& sprite, int nChannel) {
	_initSound(sprite, nChannel);
}

/**
 * L9Sound使用L9Sprite提供的声音数据资源来创建，默认播放频道数为2，一个代表背景音乐，一个代表播放的声音
 *
 * @param sprite
 *            L9Sprite
 */
L9Sound::L9Sound(L9Sprite& sprite) {
	_initSound(sprite, 2);
}
L9Sound::~L9Sound() {
	// TODO Auto-generated destructor stub
	stopAllSound();
}
void L9Sound::_playSound(int channel, int id, int loop) {
	if(_loopSoundID[channel]!=id){//换了声音，则停止播放并释放原来的声音资源
		_stopSound(channel);
	}
	if (_players[channel] == null) {
		_players[channel] = createPlayer(_sound_data[id]);
	}

	//		_players[channel].prepare();
	_loopRec[channel] = loop;

	//循环播放则没比较监听播放结束
	if (loop == -1) {
		_players[channel]->SetLooping(true);
	} else {
		//			_players[channel].setOnCompletionListener(this);
	}

	if(!isPlaying(channel))
		_players[channel]->Play();

	//		Thread.sleep(50);

}

void L9Sound::_stopSound(int channel, bool bFreeRes) {
	if (_players[channel] != null) {
		/*
		 * if (_players[channel].getState() == Player.STARTED) {
		 * _players[channel].stop(); } if (_players[channel].getState()
		 * == Player.PREFETCHED) { _players[channel].deallocate(); }
		 * _players[channel].close();
		 */
		PlayerState state = _players[channel]->GetState();
		if (state == PLAYER_STATE_PLAYING || state == PLAYER_STATE_PAUSED) {
			if (_players[channel]->IsLooping()) {
				_players[channel]->SetLooping(false);
			}
			_players[channel]->Stop();
		}
		if (bFreeRes) {
			_players[channel]->Close();
			delete _players[channel];
			_players[channel] = null;
		}
		//这里应该让线程休眠一段时间
		//				Thread.sleep(50);
	}
}
/**
 * 使用soundData数据来强制创建Player
 *
 * @param soundData
 *            byte[]
 * @return Player
 */
Player* L9Sound::createPlayer(pByte _soundData) {
	String type = "";
	byte* soundData = _soundData.pChar;
	if (soundData[0] == 'M' && soundData[1] == 'T' && soundData[2] == 'h'
			&& soundData[3] == 'd') {
		type = "mid";
	} else if (soundData[0] == 'R' && soundData[1] == 'I' && soundData[2]
			== 'F' && soundData[3] == 'F') {
		type = "wav";
	} else if (soundData[0] == '#' && soundData[1] == '!' && soundData[2]
			== 'A' && soundData[3] == 'M' && soundData[4] == 'R') {
		type = "amr";
	}
	ByteBuffer buf;
	buf.Construct(_soundData.size);
	buf.SetArray(_soundData.pChar, 0, _soundData.size);
	buf.Flip();
	Player* player = new Player();
	player->Construct(*this);
	player->OpenBuffer(buf,true);

	return player;
}
void L9Sound::_initSound(L9Sprite& sprite, int nChannel) {

	defaultInit();

	_sound_data = sprite._sound_data;
	//		_players = new Player[nChannel];
	//		_loopRec = new int[nChannel];
	//		new	Thread(this).start();

	for (int i = 0; i < nChannel; i++) {
		_players.push_back(null);
		_loopRec.push_back(0);
		_loopSoundID.push_back(-1);
	}

//	Thread* l9Thread = new Thread();
//	l9Thread->Construct(*this);
//	l9Thread->Start();
	Timer* _pTimer=new Timer();
	_pTimer->Construct(*this);
	_pTimer->Start(1000);

}
void L9Sound::defaultInit() {
	_cmd = -1;
	bRun = true;
	_bFreeRes=true;
}
void L9Sound::OnPlayerOpened(result r) {
//	L9Log("OnPlayerOpened")();
}
// 如果是循环播放则减少播放次数
void L9Sound::OnPlayerEndOfClip(void) {
	L9Log("OnPlayerEndOfClip")();
	for (int i = 0; i < _players.size(); i++) {
		if (_players[i] != null && _players[i]->GetState()== PLAYER_STATE_ENDOFCLIP) {
			if (_loopRec[i] == -1 || _loopRec[i] > 1) {
				if (_loopRec[i] > 1) {
					_loopRec[i]--;
				}
				_players[i]->Play();
			}
			break;
		}
	}
}
void L9Sound::OnPlayerBuffering(int percent) {
//	L9Log("OnPlayerBuffering")();
}
void L9Sound::OnPlayerErrorOccurred(Osp::Media::PlayerErrorReason r) {
//	L9Log("OnPlayerErrorOccurred")();
}
void L9Sound::OnPlayerInterrupted(void) {
//	L9Log("OnPlayerInterrupted")();
}
void L9Sound::OnPlayerReleased(void) {
//	L9Log("OnPlayerReleased")();
}
void L9Sound::OnPlayerSeekCompleted (result r){
//	L9Log("OnPlayerSeekCompleted")();
}
//Object* L9Sound::Run() {
//	while (bRun) {
//		switch (_cmd) {
//		case K_Sound_Cmd_Play:
//			_playSound(_channel, _sound_id, _loop);
//			break;
//		case K_Sound_Cmd_Stop:
//			_stopSound(_channel,_bFreeRes);
//			break;
//		case K_Sound_Cmd_StopAll:
//			for (int i = 0; i < _players.size(); i++) {
//				_stopSound(i);
//			}
//			break;
//		}
//		_cmd = -1;
//		Thread::Sleep(100);
//	}
//	return null;
//}
void L9Sound::OnTimerExpired(Timer& timer){
	switch (_cmd) {
	case K_Sound_Cmd_Play:
		_playSound(_channel, _sound_id, _loop);
		break;
	case K_Sound_Cmd_Stop:
		_stopSound(_channel,_bFreeRes);
		break;
	case K_Sound_Cmd_StopAll:
		for (int i = 0; i < _players.size(); i++) {
			_stopSound(i);
		}
		break;
	}
	_cmd = -1;
	timer.Start(1000);
}
/**
 * 播放某个频道上的声音,每个频道同时只能播放一个声音
 *
 * @param channel
 *            int
 * @param id
 *            int
 * @param loop
 *            int
 */
void L9Sound::playSound(int channel, int id, int loop) {
	if (id < 0) {
		return;
	}
	_cmd = K_Sound_Cmd_Play;
	_channel = channel;
	_sound_id = id;
	_loop = loop;
}

/**
 * 判断是否还在播放
 *
 * @param channel
 *            int
 * @return bool
 */
bool L9Sound::isPlaying(int channel) {
	if (_players[channel] != null) {
		if (_players[channel]->GetState() == PLAYER_STATE_PLAYING) {
			return true;
		}
	}
	return false;
}

/**
 * 停止某个频道上的声音
 *
 * @param channel
 *            int
 */
void L9Sound::stopSound(int channel,bool bFreeRes) {
	_cmd = K_Sound_Cmd_Stop;
	_channel = channel;
}

/**
 * 停止全部声音
 */
void L9Sound::stopAllSound() {
	_cmd = K_Sound_Cmd_StopAll;
}

/**
 * L9Sound声音播放采用了独立的线程模式来播放声音，endSoundThread()方法就是用来结束声音播放线程的，往往在程序退出之前调用
 */
void L9Sound::endSoundThread() {
	bRun = false;
}
};
